package com.fzkj.juc.list;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @DESCRIPTION ArrayList集合安全demo
 */
public class ArrayListDemo {

    public static void main(String[] args) {
//        arrayList_notSafe();
        arrayList_safe();
    }

    /**
     * 1、可能会抛出
     *   java.util.ConcurrentModificationException（并发修改异常）
     * 2、导致原因
     *
     * 3、解决方案
     * @param
     */
    public static void arrayList_notSafe(){
        List<String> list = new ArrayList<>();
        // 解决方案一：Vector 天生加锁
//        List<String> list = new Vector<>();
        // 解决方案二：使用 Collections.synchronizedList 完成集合的同步
//        List<String> list = Collections.synchronizedList(new ArrayList<>());
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }

    /**
     * 使用 CopyOnWriteArrayList 保证集合安全
     * 底层使用 ReentrantLock  完成集合的**写时复制**
     *   会把集合拷贝一份，对副本进行操作，不会影响原集合的读，操作结束后将原集合替换掉
     *   这样的好处就是可以对容器进行并发读，而不需要加锁。算是一种读写分离
     */
    public static void arrayList_safe(){
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}
